﻿using System;
using System.Collections;
using System.Collections.Generic;
using OpenTK;
using OpenTK.Graphics.OpenGL4;

namespace Painter3D.RenderSys
{
    /// <summary>
    /// 柔性渲染系统，可以轻易被改变
    /// </summary>
    class FlexableRenderPiple : RenderPiple
    {
        /// <summary>
        /// 渲染步骤,用何种摄像机，在那些GL设置下完成mask中物体的渲染
        /// </summary>
        public struct RenderStep
        {
            /// <summary>
            /// 使用的摄像机对象
            /// </summary>
            public Camera camera;
            /// <summary>
            /// 参与渲染的掩码
            /// </summary>
            public uint mask;
            /// <summary>
            /// GL的相关设置
            /// </summary>
            public Action seting;

            public RenderStep(Camera camera, Action seting = null, uint mask = uint.MaxValue)
            {
                this.camera = camera ?? throw new ArgumentNullException(nameof(camera));
                this.mask = mask;
                this.seting = seting;
            }
        }
        List<RenderStep> renderSteps;

        public FlexableRenderPiple(List<RenderStep> renderSteps) : base()
        {
            this.renderSteps = renderSteps ?? throw new ArgumentNullException(nameof(renderSteps));
            renderPiple = this;
        }

        /// <summary>
        /// 根据设置的渲染管线完成渲染
        /// </summary>
        public override void RenderOut()
        {

            foreach (var renderStep in renderSteps)
            {
                renderStep.seting?.Invoke();
                RenderByCmareaWithMask(renderStep.camera, renderStep.mask);
            }
        }

        public static FlexableRenderPiple InnerRenderPiple()
        {
            return new FlexableRenderPiple(new System.Collections.Generic.List<FlexableRenderPiple.RenderStep> {
                //三维不透明物体
                new FlexableRenderPiple.RenderStep(Camera.scenceMainCamera,()=>
                {
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                    GL.Enable(EnableCap.DepthTest);
                },RenderLayer.GetMask("default")),
                //三维透明物体
                new FlexableRenderPiple.RenderStep(Camera.scenceMainCamera,()=>{
                    GL.Enable(EnableCap.DepthTest);
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                },RenderLayer.GetMask("transparent")),
                //指示符号
                new FlexableRenderPiple.RenderStep(Camera.scenceMainCamera,()=>{
                    GL.LineWidth(3.0f);
                    GL.Clear(ClearBufferMask.DepthBufferBit);
                    GL.Enable(EnableCap.DepthTest);
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                },RenderLayer.GetMask("symbol")),
                //指示文字
                new FlexableRenderPiple.RenderStep(Camera.scenceMainCamera,()=>{
                    GL.Disable(EnableCap.DepthTest);
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                },RenderLayer.GetMask("lable")),
                //UI渲染
                new FlexableRenderPiple.RenderStep(Camera.uiMainCamera,()=>{
                    GL.Clear(ClearBufferMask.DepthBufferBit);
                    GL.Enable(EnableCap.DepthTest);
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                },RenderLayer.GetMask("ui")),
            });
        }


    }
}
